package com.bms.zuul.service.impl;

import com.bms.zuul.mapper.KeYanRenYuanMapper;
import com.bms.zuul.pojo.KeYanRenYuan;
import com.bms.zuul.util.JwtUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * (KeYanRenYuan)表服务实现类
 *
 * @author hlm
 * @since 2021-03-25 09:33:40
 * @version 1.0
 */
@Service("keYanRenYuanService")
public class KeYanRenYuanServiceImpl {
    @Resource
    private KeYanRenYuanMapper keYanRenYuanMapper;

//    @Resource
//    private RedisTemplate redisTemplate;

    public Map<String, Object> reg(KeYanRenYuan keYanRenYuan) {
        Map<String, Object> map = new HashMap<>();
        try {
            String miMa = keYanRenYuan.getMiMa();
            String yongHuMingCheng = keYanRenYuan.getYongHuMing();
            keYanRenYuan.setMiMa(md5(yongHuMingCheng, miMa));
            keYanRenYuanMapper.reg(keYanRenYuan);
//            redisTemplate.opsForValue().set(keYanRenYuan.getYongHuMing(), keYanRenYuan);
            map.put("code", 200);
            map.put("msg", "注册成功，请登录");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", 100200);
            map.put("msg", "注册失败，请稍候重试！");
        }
        return map;
    }

    public Map<String, Object> login(KeYanRenYuan keYanRenYuan) {
        Map<String, Object> map = new HashMap<>();
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            UsernamePasswordToken upToken = new UsernamePasswordToken(keYanRenYuan.getYongHuMing(), keYanRenYuan.getMiMa());
            upToken.setRememberMe(true);
            try {
                subject.login(upToken);    // 调用realm认证用户权限  默认会调用realm中doGetAuthenticationInfo方法
//                JWT的创建
//                String jwtToken = JwtUtils.createToken(keYanRenYuan.getYongHuMing(), keYanRenYuan.getYongHuMing(), keYanRenYuan.getYongHuMing());
//                System.out.println("jwtToken=" + jwtToken);
                map.put("code", 200);
                map.put("msg", "登录成功");
//                map.put("token", jwtToken);
                return map;
            } catch (IncorrectCredentialsException ice) {
                System.out.println("用户名/密码不匹配！");
                map.put("msg", "用户名/密码不匹配！");
            } catch (LockedAccountException lae) {
                System.out.println("账户已被冻结！");
                map.put("msg", "账户已被冻结！");
            } catch (UnknownAccountException uae) {
                System.out.println("账户不存在");
                map.put("msg", "账户不存在");
            } catch (AuthenticationException ae) {
                map.put("msg", "额外的错误");
                System.out.println(ae.getMessage());
            }
        }
        map.put("code", 10500);
        return map;

//        Object obj = redisTemplate.opsForValue().get(yongHu.getYongHuMingCheng());
//        System.out.println("obj=" + obj);
//        Map<String, Object> map = new HashMap<>();
//        if(obj != null) {
//            YongHu yongHu_redis = (YongHu)obj;
//            if(yongHu_redis.getMiMa().equals(yongHu.getMiMa())) {
//                map.put("code", 200);
//                map.put("msg", "登录成功!");
//                return map;
//            }
//        }
//        map.put("code", 10001);
//        map.put("msg", "登录失败, 用户名或者密码错误!");
//        return map;
    }

    public KeYanRenYuan getUser(String yongHuMingCheng) {
//        Object obj = redisTemplate.opsForValue().get(yongHuMingCheng);

        return keYanRenYuanMapper.login(yongHuMingCheng);
    }

    // 注册时，进行shiro加密，返回加密后的结果，如果在加入shiro之前，存在用户密码不是此方式加密的，那么将无法登录
    // 使用用户名作为盐值
    private String md5(String username, String password){
        String hashAlgorithmName = "MD5";                   // 加密方式
        ByteSource salt = ByteSource.Util.bytes(username);  // 以账号作为盐值
        int hashIterations = 11;                            // 加密11次
        return new SimpleHash(hashAlgorithmName, password, salt, hashIterations).toString();
    }
}